﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud
using System.Runtime.Serialization;
using System;
using System.ComponentModel;
using System.Threading;

namespace BrainTechLLC.ThreadSafeObjects
{
	[Serializable]
	[DataContract]
	public class ThreadSafeCounter
	{
		public override string ToString()
		{
			return _count.ToString();
		}

		public ThreadSafeCounter() { }
		public ThreadSafeCounter(int initialValue)
		{
			_count = initialValue;
		}

		[DataMember]
		protected int _count;
		public int Count { get { return _count; } }

		public void ZeroCounter()
		{
			SetCounter(0);
		}

		public void SetCounter(int count)
		{
			Interlocked.Exchange(ref _count, count);
		}

		public static ThreadSafeCounter operator ++(ThreadSafeCounter counter)
		{
			int n = Interlocked.Increment(ref counter._count);
			return counter;
		}

		public int Increment()
		{
			return Interlocked.Increment(ref _count);
		}

		public int Decrement()
		{
			return Interlocked.Decrement(ref _count);
		}

		public static ThreadSafeCounter operator --(ThreadSafeCounter counter)
		{
			int n = Interlocked.Decrement(ref counter._count);
			return counter;
		}

		public static ThreadSafeCounter operator +(ThreadSafeCounter counter, int add)
		{
			int n = Interlocked.Add(ref counter._count, add);
			return counter;
		}

		public static ThreadSafeCounter operator -(ThreadSafeCounter counter, int subtract)
		{
			int n = Interlocked.Add(ref counter._count, -subtract);
			return counter;
		}

		public static implicit operator int(ThreadSafeCounter counter) { return counter.Count; }
	}

	[Serializable]
	[DataContract]
	public class ThreadSafeCounterLong
	{
		public override string ToString()
		{
			return _count.ToString();
		}

		[DataMember]
		private long _count;
		public long Count { get { return _count; } }

		public void ZeroCounter()
		{
			SetCounter(0);
		}

		public void SetCounter(long count)
		{
			Interlocked.Exchange(ref _count, count);
		}

		public long Increment()
		{
			return Interlocked.Increment(ref _count);
		}

		public static ThreadSafeCounterLong operator ++(ThreadSafeCounterLong counter)
		{
			long n = Interlocked.Increment(ref counter._count);
			return counter;
		}

		public static ThreadSafeCounterLong operator --(ThreadSafeCounterLong counter)
		{
			long n = Interlocked.Decrement(ref counter._count);
			return counter;
		}

		public static ThreadSafeCounterLong operator +(ThreadSafeCounterLong counter, long add)
		{
			long n = Interlocked.Add(ref counter._count, add);
			return counter;
		}

		public static ThreadSafeCounterLong operator -(ThreadSafeCounterLong counter, long subtract)
		{
			long n = Interlocked.Add(ref counter._count, -subtract);
			return counter;
		}

		public static implicit operator long(ThreadSafeCounterLong counter) { return counter.Count; }
	}
}
